﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace xxpl1.Connection
{
    class Request
    {
        private readonly byte[] buffer = new byte[1000];
        private readonly StringBuilder lineTemp = new StringBuilder();
        private ParserState parserState = ParserState.Protocol;
        public Dictionary<string, string> headers = new Dictionary<string, string>();
        private int pos;
        private int len;
        private Connection connection;

        public string Status { get; set; }
        public string Version { get; set; }
        public string Description { get; set; }
        public Dictionary<string, string> Headers { get { return headers; } }

        public void GetConnection()
        {
            ConnectioPool pool = ConnectionManager.FindConnectioPool("74.125.71.60");
            connection = pool.FindConnection();
            connection.PrepareConnection();
        }

        public void Post()
        {
            string x = "GET /xpp3 HTTP/1.1\r\nHost:java2theworld0.appspot.com\r\n\r\n";
            connection.Write(Encoding.ASCII.GetBytes(x));
        }

        private void ReadHeaderLine()
        {
            do
            {
                while (pos < len)
                {
                    switch ((char)buffer[pos])
                    {
                        case '\r':
                            pos++;
                            continue;
                        case '\n':
                            pos++;
                            return;
                        default:
                            lineTemp.Append((char)buffer[pos]);
                            pos++;
                            break;
                    }
                }

                FillData();

                if (len == 0)
                    throw new Exception("Invalid header data!");

            } while (true);
        }

        private void FillData()
        {
            len = connection.Read(buffer, 0, buffer.Length);
            pos = 0;
        }

        public int Read(byte[] xx, int offset, int count)
        {
            if (len <= pos)
                FillData();

            if (len == 0)
                throw new Exception("Invalid Response Data!");

            Buffer.BlockCopy(buffer, pos, xx, offset, Math.Min(len - pos, count));

            return Math.Min(len - pos, count);
        }

        public void GetResponse()
        {
            do
            {
                switch (parserState)
                {
                    case ParserState.Protocol:
                        ReadHeaderLine();

                        string[] line = lineTemp.ToString().Split(new char[] { ' ' }, 3);

                        Version = line[0];
                        Status = line[1];
                        Description = line[2];

                        parserState = ParserState.Header;

                        lineTemp.Clear();
                        break;

                    case ParserState.Header:
                        ReadHeaderLine();

                        if (lineTemp.Length == 0)
                        {
                            parserState = ParserState.Ok;
                            goto end;
                        }

                        string[] header = lineTemp.ToString().Split(new char[] { ':' }, 2);
                        Headers.Add(header[0].Trim(), header[1].Trim());

                        lineTemp.Clear();
                        break;
                }
            } while (true);
        end:
            ;
        }

        public void ReleaseConnection()
        {
            connection.ReleaseConnection();
        }
    }
}
